package root.electronclass.electronclass.grade.widget

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import root.electronclass.electronclass.R
import root.electronclass.electronclass.ext.dp

import kotlin.math.cos
import kotlin.math.min
import kotlin.math.sin
import kotlin.random.Random

/**
 *
 * @author Lokiy
 * @date 2023/2/4 16:56
 */
class CircleProgressView : View {

    var progressColor: Int = Color.TRANSPARENT
        set(value) {
            field = value
            invalidate()
        }
    var progressWidth: Float = 0f
        set(value) {
            field = value
            invalidate()
        }

    var progress: Float = 0f
        set(value) {
            field = value
            invalidate()
        }

    //item name
    var itemText = ""

    //是否展示itemText
    var isShowItemText = true

    //是否是圆形的开始
    var isRoundEdgeProgress = false

    //是否在中间显示进度
    var isShowCenterProgress = false
    var centerProgressColor = 0xFF306EFF.toInt()
    var centerProgressTextDy = 0f
    var centerProgressTextSize = 16f
    private val rectF = RectF(0f, 0f, 0f, 0f)
    private val paint = Paint().apply {
        isAntiAlias = true
        style = Paint.Style.STROKE
    }

    private val textPaint by lazy {
        Paint().apply {
            isAntiAlias = true
            textSize = 10f
        }
    }

    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, style: Int) : super(context, attrs, style) {
        context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView).also {
            progressColor = it.getColor(R.styleable.CircleProgressView_progressColor, progressColor)
            progressWidth = it.getDimension(R.styleable.CircleProgressView_progressWidth, progressWidth)
            isShowItemText = it.getBoolean(R.styleable.CircleProgressView_isShowItemText, isShowItemText)
            isRoundEdgeProgress = it.getBoolean(R.styleable.CircleProgressView_isRoundEdgeProgress, isRoundEdgeProgress)
            isShowCenterProgress = it.getBoolean(R.styleable.CircleProgressView_isShowCenterProgressText, isShowCenterProgress)
            centerProgressColor = it.getColor(R.styleable.CircleProgressView_centerProgressTextColor, centerProgressColor)
            centerProgressTextDy = it.getDimension(R.styleable.CircleProgressView_centerProgressTextDy, centerProgressTextDy)
            centerProgressTextSize = it.getDimension(R.styleable.CircleProgressView_centerProgressTextSize, centerProgressTextSize)
            if (isInEditMode) {
                progress = Random.nextInt(100).toFloat()
                itemText = "语文"
                isRoundEdgeProgress = true
            }
            if (progressWidth == 0f) {
                progressWidth = if (isInEditMode) {
                    5f
                } else {
                    5.dp
                }
            }
            textPaint.color = Color.BLACK
        }.recycle()
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas ?: return
        paint.color = progressColor
        paint.strokeWidth = progressWidth
        val centerX = width / 2f
        val centerY = height / 2f
        val circleRadius = min(width, height).toFloat()
        val radius = circleRadius / 2 - progressWidth / 2
        rectF.set(centerX - radius, centerY - radius, centerX + radius, centerY + radius)

        val angle = 360f * (progress / 100f)
        paint.style = Paint.Style.STROKE
        canvas.drawArc(rectF, -90f + 0f, angle, false, paint)

        if (isRoundEdgeProgress) {
            paint.style = Paint.Style.FILL
            canvas.drawCircle(centerX, centerY - radius, paint.strokeWidth / 2, paint)
            val (x, y) = getXY(radius, angle.toDouble())
            canvas.translate(centerX, centerY)
            canvas.drawCircle(x, y, paint.strokeWidth / 2, paint)
            canvas.translate(-centerX, -centerY)
        }

        if (isShowCenterProgress) {
            paint.style = Paint.Style.FILL
            textPaint.color = centerProgressColor
            textPaint.textSize = centerProgressTextSize
            val text = progress.toInt().toString() + "%"
            canvas.drawText(text, centerX - textPaint.measureText(text) / 2, centerY + textPaint.textSize / 2 + centerProgressTextDy, textPaint)
        }

        if (isShowItemText) {
            textPaint.color = 0xFF071129.toInt()
            textPaint.textSize = 10f
            canvas.translate(centerX, centerY)

            val textAngle = (angle - 10).coerceAtLeast(0f)
            val (x, y) = getXY(radius, textAngle.toDouble())
            canvas.translate(x, y)

            val text = progress.toString().take(4)
            val textWidth = textPaint.measureText(text)
            if (textAngle < 275 && textAngle > 135) {
                canvas.rotate(textAngle + 180)
                canvas.drawText(text, 0f - textWidth / 2, 0f + textPaint.textSize / 2, textPaint)
                canvas.rotate(-textAngle - 180)
            } else {
                canvas.rotate(textAngle)
                canvas.drawText(text, 0f - textWidth / 2, 0f + textPaint.textSize / 2, textPaint)
                canvas.rotate(-textAngle)
            }
            canvas.save()
            canvas.translate(-x, -y)
            val dip = 30f
            val (x1, y1) = getXY(radius, 0.0)
            canvas.drawText(
                itemText,
                - dip - textPaint.measureText(itemText) / 2,
                y1  + textPaint.textSize / 2,
                textPaint
            )
            canvas.translate(-centerX, -centerY)
        }

    }

    private fun getXY(radius: Float, textAngle: Double) = if (textAngle <= 90) {
        //第一象限
        val x = radius * sin(Math.toRadians(textAngle)).toFloat()
        val y = -radius * cos(Math.toRadians(textAngle)).toFloat()
        x to y
    } else if (textAngle <= 180) {
        //第二象限
        val x = radius * cos(Math.toRadians(textAngle - 90.toDouble())).toFloat()
        val y = radius * sin(Math.toRadians(textAngle - 90.toDouble())).toFloat()
        x to y
    } else if (textAngle <= 270) {
        //第三象限
        val x = -radius * sin(Math.toRadians(textAngle - 180.toDouble())).toFloat()
        val y = radius * cos(Math.toRadians(textAngle - 180.toDouble())).toFloat()
        x to y
    } else {
        //第四象限
        val x = -radius * cos(Math.toRadians(textAngle - 270.toDouble())).toFloat()
        val y = -radius * sin(Math.toRadians(textAngle - 270.toDouble())).toFloat()
        x to y
    }

}